/**
 * Created by chris on 2017/5/22.
 */
import {Injectable} from '@angular/core';
import {Response, Headers, RequestOptions, Jsonp} from '@angular/http';
import 'rxjs/add/operator/toPromise';
import {ToastController} from "ionic-angular";

@Injectable()
export class JSonpService {

    public static envType: number = 0;
    public static host: string[] = [
        'http://192.168.3.7',
        'http://60.205.204.171'
    ];
    public static hurl = JSonpService.host[JSonpService.envType] + ':9210';
    public static reqApi = JSonpService.hurl + '/api';
    public static sevenVideo = 'http://video.castjp.top/';

    private static authPrimary: string = null;

    apiHost: string = null;
    url: string = null;
    path: string = null;
    queryObj: any = null;
    bodyObj: any = null;
    header: any = {};

    constructor(private jsonp: Jsonp, private toastCtrl: ToastController) {
        this.apiHost = JSonpService.reqApi;
    }

    public static setAuthPrimary(token) {
        JSonpService.authPrimary = token;
    }

    public instance() {
        this.url = null;
        this.path = null;
        this.queryObj = null;
        this.bodyObj = null;
        if (JSonpService.authPrimary) {
            this.header.token = JSonpService.authPrimary;
        }
        return this;
    }

    public setUrl(url: string) {
        this.url = url;
        return this;
    }

    public setPath(path: string) {
        this.path = path;
        return this;
    }

    public setQuery(queryObj: any) {
        this.queryObj = queryObj;
        return this;
    }

    public setBody(bodyObj: any) {
        this.bodyObj = bodyObj;
        return this;
    }

    public setHeader(header: any) {
        this.header = header;
        return this;
    }

    private checkRequest() {
        let reqData = this.path ? this.path : this.apiHost + this.url;
        if (this.queryObj) {
            reqData += this.toQueryString(this.queryObj)
        }
        return reqData;
    }

    public getRequest() {
        let reqPath = this.checkRequest();
        let headers = new Headers(this.header);
        return this.jsonp.get(reqPath, new RequestOptions({headers: headers}))
            .toPromise()
            .then(res => this.handleSuccess(res.json()))
            .catch(error => this.handleError(error));
    }

    public postRequest() {
        let reqPath = this.checkRequest();
        let headers = new Headers(this.header);
        return this.jsonp.post(reqPath, this.bodyObj, new RequestOptions({headers: headers}))
            .toPromise()
            .then(res => this.handleSuccess(res.json()))
            .catch(error => this.handleError(error));
    }

    public postStrRequest() {
        let reqPath = this.checkRequest();
        let headers = new Headers(this.header);
        return this.jsonp.post(reqPath, this.toBodyString(this.bodyObj), new RequestOptions({headers: headers}))
            .toPromise()
            .then(res => this.handleSuccess(res.json()))
            .catch(error => this.handleError(error));
    }

    public putRequest() {
        let reqPath = this.checkRequest();
        let headers = new Headers(this.header);
        return this.jsonp.put(reqPath, this.bodyObj, new RequestOptions({headers: headers}))
            .toPromise()
            .then(res => this.handleSuccess(res.json()))
            .catch(error => this.handleError(error));
    }

    public delRequest() {
        let reqPath = this.checkRequest();
        let headers = new Headers(this.header);
        return this.jsonp.delete(reqPath, new RequestOptions({headers: headers}))
            .toPromise()
            .then(res => this.handleSuccess(res.json()))
            .catch(error => this.handleError(error));
    }


    private handleSuccess(result) {
        console.log(result);
        if (result.status != 0) {
            this.toastCtrl.create()
                .setMessage(result.msg)
                .setDuration(2000)
                .setPosition('middle')
                .present();
        }
        return result;
    }

    private handleError(error: Response | any) {
        let msg = '请求失败';
        if (error.status == 0) {
            msg = '请求地址错误';
        }
        if (error.status == 400) {
            msg = '请求无效';
            console.log('请检查参数类型是否匹配');
        }
        if (error.status == 403) {
            console.log(error.msg);
        }
        if (error.status == 404) {
            msg = '请求资源不存在';
            console.error(msg+'，请检查路径是否正确');
        }
        console.log('handleError:', error);
        return {status: 2, msg: msg};
    }

    /**
     * @param obj　参数对象
     * @return {string}　参数字符串
     * @example
     *  声明: var obj= {'name':'小军',age:23};
     *  调用: toQueryString(obj);
     *  返回: "?name=%E5%B0%8F%E5%86%9B&age=23"
     */
    private toQueryString(obj) {
        let ret = [];
        for (let key in obj) {
            key = encodeURIComponent(key);
            let values = obj[key];
            if (values && values.constructor == Array) {//数组
                let queryValues = [];
                for (let i = 0, len = values.length, value; i < len; i++) {
                    value = values[i];
                    queryValues.push(this.toQueryPair(key, value));
                }
                ret = ret.concat(queryValues);
            } else { //字符串
                ret.push(this.toQueryPair(key, values));
            }
        }
        return '?' + ret.join('&');
    }

    /**
     *
     * @param obj
     * @return {string}
     *  声明: var obj= {'name':'小军',age:23};
     *  调用: toQueryString(obj);
     *  返回: "name=%E5%B0%8F%E5%86%9B&age=23"
     */
    private toBodyString(obj) {
        let ret = [];
        for (let key in obj) {
            key = encodeURIComponent(key);
            let values = obj[key];
            if (values && values.constructor == Array) {//数组
                let queryValues = [];
                for (let i = 0, len = values.length, value; i < len; i++) {
                    value = values[i];
                    queryValues.push(this.toQueryPair(key, value));
                }
                ret = ret.concat(queryValues);
            } else { //字符串
                ret.push(this.toQueryPair(key, values));
            }
        }
        return ret.join('&');
    }

    private toQueryPair(key, value) {
        if (typeof value == 'undefined') {
            return key;
        }
        return key + '=' + encodeURIComponent(value === null ? '' : String(value));
    }
}
